<template>
  <div>
    <h2>{{ activeTab }}</h2>
    <div class="table-container">
      <div class="header-controls">
        <div style="display: flex; gap: 10px;">
          <!-- XML名称选择 -->
          <el-select v-model="activeTab" placeholder="请选择XML文件" style="width: 200px;" filterable>
            <el-option v-for="xml in xmlShowList" :key="xml.xmlName" :label="xml.xmlName" :value="xml.xmlName" />
          </el-select>

          <el-select v-model="modifyName" placeholder="修改人" style="width: 200px;" filterable clearable
            @change="changeSelectedModifyName">
            <el-option v-for="author in authorOptions" :label="author" :value="author" />
          </el-select>

          <el-select v-model="modifyMsg" placeholder="修改单" style="width: 200px;" filterable clearable>
            <el-option v-for="msg in msgOptions" :label="msg" :value="msg" />
          </el-select>
          <!-- <el-select v-model="modifyMsg" placeholder="修改单" style="width: 200px;" filterable clearable>
            <el-option v-for="msg in ['1', '2', '3']" :label="msg" :value="msg" />
          </el-select> -->

        </div>
      </div>
      <!-- 表格组件 -->
      <div class="table-show">
        <el-tabs v-model="activeSheet" type="card" @tab-click="handleSheetTabClick" class="sheet-tabs">
          <el-tab-pane v-for="(sheet, index) in xmlShowList.find(xml => xml.xmlName === activeTab)?.sheetName" :key="sheet"
            :label="sheet" :name="sheet">
            <hot-table v-if="activeTab && activeSheet === sheet" :ref="(el: any) => { hotTableComponents[index] = el }"
              :settings="getTableSettings(sheet)"></hot-table>
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>


  </div>

</template>

<script setup lang="ts">
import { ref, onMounted, nextTick, watch, inject, onUnmounted } from 'vue'
import { HotTable } from '@handsontable/vue3'
import { registerAllModules } from 'handsontable/registry'
import { registerLanguageDictionary, zhCN } from 'handsontable/i18n'
import Handsontable from 'handsontable'
import 'handsontable/dist/handsontable.full.min.css'
import type { Axios } from 'axios'
import { ChangeRecord, SheetData, SvnLog, transformXmlChangeData, XmlChangeData } from './XmlChangeVisual'
import { ElMessage } from 'element-plus'
import { xmlChangeTempJsonData } from './XmlChangeTempData'

//  ---------------------------------------------- var define ----------------------------------------------
// 注册所有Handsontable模块
registerAllModules()
// 注册中文语言包
registerLanguageDictionary(zhCN)

// 注入全局axios实例
const http = inject<Axios>('http')

const xmlChangeDataList = ref<XmlChangeData>()

// 当前激活的页签
const activeTab = ref<string>('')
// 当前激活的表格sheet
const activeSheet = ref<string>('')
interface XmlActiveTable {
  xmlName: string
  sheetName: string[]
}
const xmlList = ref<XmlActiveTable[]>([])
const xmlShowList = ref<XmlActiveTable[]>([])

interface HotTableMethods {
  hotInstance: Handsontable
}

// 修改人
const modifyName = ref<string>('')
const selectedModifyName = ref<string | undefined>(undefined)
// 修改表单
const modifyMsg = ref<string>('')
const selectedModifyMsg = ref<string | undefined>(undefined)

// 缓存转换后的选项列表，避免重复计算
const authorOptions = ref<string[]>([])
const msgOptions = ref<string[]>([])

// 使用一个对象存储所有表格实例
const hotTableComponents = ref<HotTableMethods[]>([])

// 存储每个sheet的修改信息映射 (row, col) -> { isModified: boolean, author: string }
const sheetModificationMap = ref<Map<string, Map<string, { isModified: boolean, author: string }>>>(new Map())

const svnVer2ChangeDataList = new Map<number, { author: string, msg: string, svn_ver: number }>()
const author2ChangeDataList = new Map<string, { author: string, msg: string, svn_ver: number }>()
const svnMsg2ChangeDataList = new Map<string, { author: string, msg: string, svn_ver: number }>()

// 为每个表格创建一个设置对象
const tableSettings = ref<Map<string, any>>(new Map())

// 表格高度
const tableHeight = ref(500)

// 计算表格高度
const calculateTableHeight = () => {
  // 计算总的偏移量，考虑header-controls的高度和页签高度
  const totalOffset = 150 // header + tabs + padding

  // 设置表格高度
  tableHeight.value = window.innerHeight - totalOffset
}

// 获取指定sheet的表格设置
const getTableSettings = (sheetName: string) => {
  // 如果该sheet没有对应的设置，创建一个新的基础设置
  if (!tableSettings.value.has(sheetName)) {
    // 基于模板复制一个新的设置对象
    const settings = JSON.parse(JSON.stringify(tableSettingsTemplate.value))
    tableSettings.value.set(sheetName, settings)
  }

  return tableSettings.value.get(sheetName)
}

// 表格配置
const tableSettingsTemplate = ref({
  data: [
    ['', 'default', 'default', 'default', 'default', 'default', 'default'],
    ['2017', 10, 11, 12, 13, 15, 16],
    ['2018', 10, 11, 12, 13, 15, 16],
    ['2019', 10, 11, 12, 13, 15, 16],
    ['2020', 10, 11, 12, 13, 15, 16],
    ['2021', 10, 11, 12, 13, 15, 16],
  ],                             // 表格数据源，初始为空数组
  dataSchema: [],                // 表格数据结构
  minSpareRows: 0,               // 最小剩余行数，0表示不自动添加空白行
  width: '100%',                 // 表格宽度，占满容器
  height: tableHeight.value,     // 设置固定高度，确保Y轴滚动在表格内
  stretchH: 'none',              // 列宽拉伸模式，none表示不自动拉伸
  fixedColumnsStart: 0,          // 左侧固定的列数，前两列将始终可见
  colHeaders: ['nihao', 'lala'], // 列标题文本数组
  columns: [
    { data: 0 },
    { data: 1 },
    { data: 2 },
    { data: 3 },
    { data: 4 },
    { data: 5 },
    { data: 6 },
  ],
  contextMenu: false,                                           // 禁用右键上下文菜单
  filters: false,                                               // 禁用过滤功能
  dropdownMenu: false,                                          // 禁用下拉菜单
  language: 'zh-CN',                                            // 设置语言为中文
  rowHeaders: true,                                             // 显示行标题（行号）
  manualColumnResize: true,                                     // 允许手动调整列宽
  manualRowResize: true,                                        // 允许手动调整行高
  columnSorting: false,                                         // 禁用列排序功能
  wordWrap: false,                                              // 禁用文字自动换行
  autoColumnSize: false,                                        // 禁用自动调整列宽
  licenseKey: 'non-commercial-and-evaluation',                  // Handsontable许可证密钥
  // 自定义单元格渲染器
  cells: function (_row: number, _col: number, _prop: string) {
    return {
      renderer: function (
        instance: Handsontable,
        td: HTMLTableCellElement,
        row: number,
        col: number,
        prop: string | number,
        value: any,
        cellProperties: Handsontable.CellProperties
      ) {
        // 使用默认渲染器
        Handsontable.renderers.TextRenderer(
          instance,
          td,
          row,
          col,
          prop,
          value,
          cellProperties
        );

        // 获取当前sheet的修改信息
        const currentSheetKey = `${activeTab.value}_${activeSheet.value}`
        const modificationMap = sheetModificationMap.value.get(currentSheetKey)

        if (modificationMap) {
          const cellKey = `${row}_${col}`
          const modificationInfo = modificationMap.get(cellKey)

          if (modificationInfo && modificationInfo.isModified) {
            // 设置黄色背景
            td.style.backgroundColor = '#FFFACD'

            // 如果有筛选修改人，则隐藏修改人信息，只显示红色内容
            if (selectedModifyName.value) {
              // 有筛选时，只显示红色的修改内容
              const content = value || ''
              td.innerHTML = `<span style="color: #ff4444;">${content}</span>`
            } else {
              // 无筛选时，显示修改人信息和红色内容
              const author = modificationInfo.author
              const content = value || ''
              td.innerHTML = `<span style="color: #333;">(${author})</span><span style="color: #ff4444;">${content}</span>`
            }
          }
        }
      }
    };
  }
})

//  ---------------------------------------------- function define ---------------------------------------------

const changeSelectedModifyName = () => {
  selectedModifyName.value = modifyName.value

  xmlShowList.value = []

  // 清空修改信息映射
  sheetModificationMap.value.clear()

  activeTab.value = ''
  activeSheet.value = ''
  // 处理所有XML
  for (const xml of xmlList.value) {
    const localShowSheetList = changeActiveTab(xml.xmlName)
    if (localShowSheetList && localShowSheetList.length > 0) {
      xmlShowList.value.push({
        xmlName: xml.xmlName,
        sheetName: localShowSheetList
      })
    }
  }

  nextTick(() => {
    activeTab.value = xmlShowList.value[0].xmlName || ''
    // nmd 一层不够就多一层
    nextTick(() => {
      nextTick(() => {
        activeSheet.value = xmlShowList.value[0].sheetName[0] || ''
      })
    })
  })
}

const changeSelectedModifyMsg = (msg: string) => {
  modifyMsg.value = msg
}

// 数据变化时更新渲染
const changeActiveTab = (tab: string) => {
  if (!tab || !xmlChangeDataList.value) return;

  const xmlData = xmlChangeDataList.value.change_xmls.get(tab);
  if (!xmlData) return;

  // 获取该XML下所有表单（sheets）
  const sheets = Array.from(xmlData.change_sheets.entries());

  // 清空旧的表格设置
  tableSettings.value.clear();
  const localShowSheetList: string[] = []

  // 处理每个sheet的数据
  sheets.forEach(([sheetName, sheetData], index) => {
    // 创建表格设置
    const changedSheetdata = genSheetData(tab, sheetData, svnVer2ChangeDataList, selectedModifyName.value, selectedModifyMsg.value) || []
    if (changedSheetdata.length > 0) {
      localShowSheetList.push(sheetName)
    }
    const settings = {
      ...tableSettingsTemplate.value,
      // 使用列名作为表头
      colHeaders: sheetData.col_names,
      // 生成表格数据
      data: changedSheetdata,
      // 配置列
      columns: sheetData.col_names.map((colHeader) => ({
        data: colHeader,
        width: 120
      }))
    };

    // 保存设置
    tableSettings.value.set(sheetName, settings);

    // 下一个渲染周期更新表格
    nextTick(() => {
      // 确保表格组件已经挂载
      if (hotTableComponents.value[index]?.hotInstance) {
        // 更新表格数据

        hotTableComponents.value[index].hotInstance.updateSettings({
          colHeaders: settings.colHeaders,
          data: settings.data,
          columns: settings.columns
        }, false);

        if (localShowSheetList.length > 0) {
          // 设置活动的XML和sheet
          activeSheet.value = localShowSheetList[0]
        }

      }
    });

  });
  return localShowSheetList
}

const genSheetData = (
  xmlName: string,
  sheetData: SheetData | undefined,
  svnVer2ChangeDataList: Map<number, SvnLog>,
  selectedModifyName: string | undefined,
  selectedModifyMsg: string | undefined
) => {
  if (!sheetData || !sheetData.changes) return [];

  // 创建当前sheet的修改信息映射，使用传入的sheetName参数
  const currentSheetKey = `${xmlName}_${sheetData.sheet_name}`
  const modificationMap = new Map<string, { isModified: boolean, author: string }>()

  // 将变更记录转换为表格数据
  const changedSheetdata = []
  let displayRowIndex = 0 // 实际显示的行索引

  for (let originalRowIndex = 0; originalRowIndex < sheetData.changes.length; originalRowIndex++) {
    const change = sheetData.changes[originalRowIndex]
    const changeList = change.change_list
    const rowData: Record<string, string> = { ...change.old_data };
    const { hasChanger, rowData: changedRowData, modifiedFields } = rowDataWithChanger(rowData, svnVer2ChangeDataList, changeList, selectedModifyName, selectedModifyMsg)

    if (hasChanger) {
      // 记录修改信息到映射中，使用实际显示的行索引
      sheetData.col_names.forEach((colName, colIndex) => {
        const cellKey = `${displayRowIndex}_${colIndex}` // 使用displayRowIndex而不是originalRowIndex
        const isModified = modifiedFields.has(colName)
        if (isModified) {
          const changeName = getFieldAuthor(changeList, colName, svnVer2ChangeDataList)
          modificationMap.set(cellKey, { isModified: true, author: changeName })
        }
      })

      changedSheetdata.push(changedRowData);
      displayRowIndex++ // 只有当行被添加到显示数据时才增加显示行索引
    }
  }

  // 保存修改信息映射
  sheetModificationMap.value.set(currentSheetKey, modificationMap)

  return changedSheetdata;
}

// 获取字段的修改作者
const getFieldAuthor = (
  changeList: Array<{ field: string, value: string, svn_ver: number }>,
  fieldName: string,
  svnChangeMap: Map<number, SvnLog>
): string => {
  const fieldChange = changeList.find(change => change.field === fieldName)
  if (fieldChange) {
    return svnChangeMap.get(fieldChange.svn_ver)?.author || fieldChange.svn_ver.toString()
  }
  return ''
}

const rowDataWithChanger = (
  rowData: Record<string, string>,
  svnChangeMap: Map<number, SvnLog>,
  changeList: Array<{ field: string, value: string, svn_ver: number }>,
  selectedModifyName: string | undefined,
  _selectedModifyMsg: string | undefined
) => {
  let hasChanger = false
  const modifiedFields = new Set<string>()

  changeList.forEach((change: { field: string, value: string, svn_ver: number }) => {
    const changeName = svnChangeMap.get(change.svn_ver)?.author || change.svn_ver;
    if (!selectedModifyName) {
      // 直接使用修改后的值，不拼接修改人信息
      rowData[change.field] = change.value;
      modifiedFields.add(change.field)
      hasChanger = true
    } else if (selectedModifyName && changeName === selectedModifyName) {
      // 直接使用修改后的值，不拼接修改人信息
      rowData[change.field] = change.value;
      modifiedFields.add(change.field)
      hasChanger = true
    } else {
      rowData[change.field] = change.value;
    }
  });

  return { hasChanger, rowData, modifiedFields };
}

// 监听页签变化，确保表格正确渲染
watch(() => activeTab.value, (newXmlName, _oldXmlName) => {
  // 重置表格实例数组
  hotTableComponents.value = [];

  // 设置第一个sheet为激活状态
  const currentXml = xmlList.value.find(xml => xml.xmlName === newXmlName);
  if (currentXml && currentXml.sheetName.length > 0) {
    activeSheet.value = currentXml.sheetName[0];
  }

  // 下一个渲染周期后更新表格数据
  nextTick(() => {
    changeActiveTab(newXmlName);
    // 重新计算表格高度
    calculateTableHeight();
    // 更新表格高度设置
    updateTableHeight();
  });
});

// 更新选项列表
const updateSelectOptions = () => {
  // 确保先把数据转换为数组再赋值给ref，这样Vue才能正确追踪变化
  authorOptions.value = Array.from(author2ChangeDataList.keys());
  msgOptions.value = Array.from(svnMsg2ChangeDataList.keys());
}

// 正式获取数据
const fetch_xml_change_data = () => {
  const urlParams = new URLSearchParams(window.location.hash.split('?')[1]);
  const fileParam = urlParams.get('file');
  console.log('fileParam', fileParam)
  // 安全检查确保http存在
  if (http && fileParam) {
    // 使用await确保数据加载完成后再进行后续操作
    return http.get(`http://192.168.9.68/xml_db/taxi_data/${fileParam}`)
  } else {
    return Promise.reject('http不存在')
  }
}

// 测试数据
// const fetch_xml_change_data = () => {
//   return Promise.resolve({ data: xmlChangeTempJsonData })
// }

onMounted(() => {
  try {
    // 计算初始表格高度
    calculateTableHeight()

    // 添加窗口大小变化监听，重新计算表格高度
    window.addEventListener('resize', calculateTableHeight)

    // 创建变量存储XML数据
    let changeXmlData = {};

    // 安全检查确保http存在
    fetch_xml_change_data()
      .then((res) => {
        // 检查响应是否有效
        if (res && res.data) {
          // 使用API返回的数据
          changeXmlData = res.data;
          // 加载表格数据
          xmlChangeDataList.value = transformXmlChangeData(changeXmlData);
          // 重新生成XML列表
          xmlList.value = [];
          for (const [xmlName, xmlData] of xmlChangeDataList.value.change_xmls) {
            xmlList.value.push({
              xmlName: xmlName,
              sheetName: Array.from(xmlData.change_sheets.keys())
            });
          }
          xmlShowList.value = xmlList.value

          // 处理SVN日志数据
          svnVer2ChangeDataList.clear();
          author2ChangeDataList.clear();
          svnMsg2ChangeDataList.clear();

          xmlChangeDataList.value?.svn_logs.forEach((svnLog) => {
            svnVer2ChangeDataList.set(svnLog.svn_ver, { author: svnLog.author, msg: svnLog.msg, svn_ver: svnLog.svn_ver });
            author2ChangeDataList.set(svnLog.author, { author: svnLog.author, msg: svnLog.msg, svn_ver: svnLog.svn_ver });
            svnMsg2ChangeDataList.set(svnLog.msg, { author: svnLog.author, msg: svnLog.msg, svn_ver: svnLog.svn_ver });
          });

          // 更新选项列表
          updateSelectOptions();

          // 激活第一个页签
          if (xmlShowList.value.length > 0) {
            activeTab.value = xmlShowList.value[0].xmlName;

            // 激活第一个sheet
            const firstXml = xmlShowList.value[0];
            if (firstXml.sheetName.length > 0) {
              activeSheet.value = firstXml.sheetName[0];
            }

            // 等待表格组件挂载完成后更新数据
            nextTick(() => {
              changeActiveTab(activeTab.value);
            });
          }
        }
      })
      .catch((error) => {
        console.error("获取XML数据失败:", error);
        ElMessage.error("获取XML数据失败")
      });
  } catch (error) {
    ElMessage.error("加载表格数据失败")
    console.error('加载表格数据失败', error)
  }
});

// 组件卸载时移除事件监听
onUnmounted(() => {
  window.removeEventListener('resize', calculateTableHeight)
});

// 更新当前表格高度
const updateTableHeight = () => {
  const sheets = xmlList.value.find(xml => xml.xmlName === activeTab.value)?.sheetName || []
  const index = sheets.findIndex(s => s === activeSheet.value)

  if (index >= 0 && hotTableComponents.value[index]?.hotInstance) {
    hotTableComponents.value[index].hotInstance.updateSettings({
      height: tableHeight.value
    }, false)
  }
}

// 处理sheet页签点击
const handleSheetTabClick = (tab: any) => {
  console.log('上一个表格页签:', activeSheet.value)
  console.log('切换到表格页签:', tab.props.name)
  if (activeSheet.value === tab.props.name) {
    return;
  }
  // 下一个渲染周期更新表格
  nextTick(() => {
    // 查找当前表格索引
    const sheets = xmlList.value.find(xml => xml.xmlName === activeTab.value)?.sheetName || []
    const index = sheets.findIndex(s => s === tab.props.name)

    // 确保表格组件已经挂载
    if (index >= 0 && hotTableComponents.value[index]?.hotInstance) {
      // 触发表格重新渲染
      hotTableComponents.value[index].hotInstance.render()
      // 更新表格高度
      updateTableHeight()
    }
  })
}

</script>

<style scoped>
.handsontable {
  padding: 0 0 10px 0;
}

.table-container {
  margin-top: 20px;
  position: relative;
}

.table-show {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  background-color: #fff;
  padding: 0 10px;
}

.table-show>div {
  padding: 0 10px 5px 10px;
  border-bottom: 1px dashed #ebeef5;
}

.table-show>div:last-child {
  border-bottom: none;
}

.table-show h2 {
  margin-top: 10px;
  margin-bottom: 5px;
  font-size: 16px;
  font-weight: bold;
  color: #333;
  border-left: 4px solid #409eff;
  padding-left: 10px;
  position: sticky;
  top: 0;
  background-color: #f9f9f9;
  z-index: 10;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

/* 选中单元格展示区域样式 */
.selected-cell-display {
  margin: 10px 0;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 15px;
  background-color: #f9f9f9;
}

.display-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  font-weight: bold;
}

.display-content {
  padding: 0 10px;
}

/* 主内容区域保持滚动条 */
:deep(.ht_master.handsontable .wtHolder) {
  overflow: auto !important;
}

/* 隐藏顶部列标题的滚动条 */
:deep(.ht_clone_top.handsontable .wtHolder) {
  overflow: hidden !important;
  overflow-x: hidden !important;
  overflow-y: hidden !important;
}

/* 隐藏左侧行号的滚动条 */
:deep(.ht_clone_left.handsontable .wtHolder) {
  overflow: hidden !important;
  overflow-x: hidden !important;
  overflow-y: hidden !important;
}

/* 隐藏左上角的滚动条 */
:deep(.ht_clone_top_left_corner.handsontable .wtHolder) {
  overflow: hidden !important;
  overflow-x: hidden !important;
  overflow-y: hidden !important;
}

:deep(.handsontable td) {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 4px 6px !important;
  position: relative;
}

:deep(.handsontable td[class*="current"]) {
  z-index: 2;
}

:deep(.handsontable td:not(:empty)) {
  z-index: 1;
}

:deep(.handsontable td:empty) {
  z-index: 0;
}

/* 移除其他可能影响的通用样式 */
:deep(.handsontable .wtHolder) {
  overflow: visible !important;
}

:deep(.handsontable .ht_clone_top) {
  z-index: 101;
}

:deep(.handsontable .ht_clone_left) {
  z-index: 102;
}

:deep(.handsontable .ht_clone_top_left_corner) {
  z-index: 103;
}

:deep(.handsontable ::-webkit-scrollbar) {
  width: 8px;
  height: 8px;
}

:deep(.handsontable ::-webkit-scrollbar-track) {
  background: #f1f1f1;
  border-radius: 4px;
}

:deep(.handsontable ::-webkit-scrollbar-thumb) {
  background: #888;
  border-radius: 4px;
}

:deep(.handsontable ::-webkit-scrollbar-thumb:hover) {
  background: #555;
}

/* 按钮样式 */
:deep(.el-button--small) {
  padding: 4px 8px;
  font-size: 12px;
  line-height: 1.2;
}

.header-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.search-controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* 页签样式 */
.sheet-tabs {
  margin-top: 10px;
}

:deep(.el-tabs__item) {
  font-size: 14px;
  height: 36px;
  line-height: 36px;
  padding: 0 15px;
}

:deep(.el-tabs__item.is-active) {
  font-weight: bold;
  color: #409eff;
}

:deep(.el-tabs__content) {
  padding: 15px 0;
  height: auto;
  overflow: visible;
}

/* 隐藏顶部列标题的滚动条 */
:deep(.ht_clone_top.handsontable .wtHolder) {
  overflow: hidden !important;
  overflow-x: hidden !important;
  overflow-y: hidden !important;
}
</style>
